package com.leon.android.component.workmanager_test

import android.os.Bundle
import androidx.work.*
import com.apkfuns.logutils.LogUtils
import com.leon.android.arch.mvvv.base.BaseActivity
import com.leon.android.component.workmanager_test.task.PeriodicUploadWorker
import com.leon.android.component.workmanager_test.task.UploadWorker
import com.leon.common.utils.SpUtils
import kotlinx.android.synthetic.main.wm_activity_main.*
import org.jetbrains.anko.sdk27.coroutines.onClick
import java.util.*
import java.util.concurrent.TimeUnit

class WmMainActivity : BaseActivity() {
    override val layoutId: Int
        get() = R.layout.wm_activity_main

    override fun initData(savedInstanceState: Bundle?) {
    }

    override fun initView(savedInstanceState: Bundle?) {
        onceWorkBtn.onClick {
            val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
                .setInputData(Data.Builder().putString("type", "OnTimeImmediately").build())
                .build()
            WorkManager.getInstance(application).enqueue(uploadWorkRequest)
        }

        constraintsWorkBtn.onClick {
            // Create a Constraints object that defines when the task should run
            val constraints = Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build()

            // ...then create a OneTimeWorkRequest that uses those constraints
            val uploadWorker = OneTimeWorkRequestBuilder<UploadWorker>()
                .setConstraints(constraints)
                .setInputData(Data.Builder().putString("type", "Constraints").build())
                .build()
            WorkManager.getInstance(application).enqueue(uploadWorker)
        }

        retryWorkBtn.onClick {
            val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
                .setBackoffCriteria(
                    BackoffPolicy.LINEAR, // Linear 线性叠加延迟时间， EXPONENTIAL 指数级增长任务执行重试间隔
                    5,
                    TimeUnit.SECONDS
                )
                .setInputData(Data.Builder().putString("type", "LINEAR").build())
                .build()

            WorkManager.getInstance(application).enqueue(uploadWorkRequest)
        }
        retryWorkBtn2.onClick {
            val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
                .setBackoffCriteria(
                    BackoffPolicy.EXPONENTIAL, // Linear 线性叠加延迟时间， EXPONENTIAL 指数级增长任务执行重试间隔
                    5,
                    TimeUnit.SECONDS
                )
                .setInputData(Data.Builder().putString("type", "EXPONENTIAL").build())
                .build()

            WorkManager.getInstance(application).enqueue(uploadWorkRequest)
        }

        observeWorkStateBtn.onClick {
            val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
                .build()
            WorkManager.getInstance(application).enqueue(uploadWorkRequest)
            SpUtils.getInstance().put("last", uploadWorkRequest.id.toString())


            WorkManager.getInstance(applicationContext)
                .getWorkInfoByIdLiveData(UUID.fromString(SpUtils.getInstance().getString("last")))
                .observe(this@WmMainActivity,
                    androidx.lifecycle.Observer {
                        LogUtils.d(it.state)
                    })
        }

        chainWorkBtn.onClick {
            val filter1 = OneTimeWorkRequestBuilder<UploadWorker>()
                .setInputData(Data.Builder().putString("type", "filter1").build())
                .build()


            val filter2 = OneTimeWorkRequestBuilder<UploadWorker>()
                .setInputData(Data.Builder().putString("type", "filter2").build())
                .build()

            val filter3 = OneTimeWorkRequestBuilder<UploadWorker>()
                .setInputData(Data.Builder().putString("type", "filter3").build())
                .build()


            val compress = OneTimeWorkRequestBuilder<UploadWorker>()
//                .setInputMerger(ArrayCreatingInputMerger::class.java)
//            OverwritingInputMerger 会尝试将所有输入中的所有键添加到输出中。如果发生冲突，它会覆盖先前设置的键。
//
//            ArrayCreatingInputMerger 会尝试合并输入，并在必要时创建数组。
                .setInputData(Data.Builder().putString("type", "compress").build())
                .build()


            val upload = OneTimeWorkRequestBuilder<UploadWorker>()
                .setInputData(Data.Builder().putString("type", "upload").build())
                .build()


            WorkManager.getInstance(application)
                // Candidates to run in parallel
                .beginWith(listOf(filter1, filter2, filter3))
                // Dependent work (only runs after all previous work in chain)
                .then(compress)
                .then(upload)
                // Don't forget to enqueue()
                .enqueue()

        }


        repeatWorkBtn.onClick {

//            注意：可以定义的最短重复间隔是 15 分钟（与 JobScheduler API 相同）。
            val constraints = Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build()

            val saveRequest =
                PeriodicWorkRequestBuilder<PeriodicUploadWorker>(15, TimeUnit.MINUTES)
                    .setInputData(Data.Builder().putString("type","PeriodicWork").build())
                    .setConstraints(constraints)
                    .build()

            WorkManager.getInstance(this@WmMainActivity)
                .enqueue(saveRequest)
            WorkManager.getInstance(application).getWorkInfoByIdLiveData(saveRequest.id).observe(this@WmMainActivity,
                androidx.lifecycle.Observer {
                    LogUtils.d("${it.state} ${it.runAttemptCount}")
                })

        }

        singleWorkBtn.onClick {
            val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
                .setInputData(Data.Builder().putString("type", "singleTask").build())
                .build()
//            ExistingWorkPolicy.REPLACE 冲突解决策略
            WorkManager.getInstance(application).enqueueUniqueWork("Single Task",ExistingWorkPolicy.REPLACE,uploadWorkRequest)
        }


//        class CoroutineDownloadWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
//
//
//            override suspend fun doWork(): Result = coroutineScope {
//                val jobs = (0 until 100).map {
//                    async {
////                        downloadSynchronously("https://www.google.com")
//                    }
//                }
//
//                // awaitAll will throw an exception if a download fails, which CoroutineWorker will treat as a failure
//                jobs.awaitAll()
//                Result.success()
//            }
//        }


    }

    override fun bindModel() {
    }
}
